﻿using CXW.Core.Services;
using System;
using System.Windows.Forms;

namespace CXW.Core.Sharp.Sda
{
    internal sealed class CallHelper : MarshalByRefObject
    {
        SharpDevelopHost.CallbackHelper callback;

        public override object InitializeLifetimeService()
        {
            return null;
        }

        #region Initialize Core
        public void InitSharpDevelopCore(SharpDevelopHost.CallbackHelper callback, StartupSettings properties)
        {
            ServiceManager.Instance = new SDServiceManager();

            LoggingService.Info("InitSharpDevelop...");
            this.callback = callback;
            CoreStartup startup = new CoreStartup(properties.ApplicationName);
            if (!System.Diagnostics.Debugger.IsAttached)
            {
                ExceptionBox.RegisterExceptionBoxForUnhandledExceptions();
            }
            startup.ConfigDirectory = properties.ConfigDirectory;
            startup.DataDirectory = properties.DataDirectory;

            if (properties.ApplicationRootPath != null)
            {
                FileUtility.ApplicationRootPath = properties.ApplicationRootPath;
            }

            startup.StartCoreServices();

            LoggingService.Info("Looking for AddIns...");

            foreach (string dir in properties.addInDirectories)
            {
                startup.AddAddInsFromDirectory(dir);
            }

            LoggingService.Info("Loading AddInTree...");
            startup.RunInitialization();

            LoggingService.Info("InitSharpDevelop finished");

            DevExpress.UserSkins.BonusSkins.Register();
            DevExpress.Skins.SkinManager.EnableFormSkins();

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            LanguageService.ValidateLanguage();
        }
        #endregion

        #region Initialize and run Workbench
        public void RunWorkbench()
        {
            WorkbenchStartup wbc = new WorkbenchStartup();
            LoggingService.Info("Initializing workbench...");
            wbc.InitializeWorkbench();

            RunWorkbenchInitializedCommands();

            LoggingService.Info("Starting workbench...");

            try
            {
                callback.BeforeRunWorkbench();

                wbc.Run();
            }
            finally
            {
                LoggingService.Info("Unloading services...");
                try
                {
                    PropertyService.Save();
                }
                catch (Exception ex)
                {
                    LoggingService.Warn("Exception during unloading", ex);
                }
            }
            LoggingService.Info("Finished running workbench.");
            callback.WorkbenchClosed();
        }

        void RunWorkbenchInitializedCommands()
        {
            foreach (ICommand command in AddInTree.BuildItems<ICommand>("/Workspace/AutostartAfterWorkbenchInitialized", null, false))
            {
                try
                {
                    command.Run();
                }
                catch (Exception ex)
                {
                    // allow startup to continue if some commands fail
                    MessageService.ShowError(ex.Message);
                }
            }
        }
        #endregion

        public bool CloseWorkbench(bool force)
        {
            if (WorkbenchSingleton.InvokeRequired)
            {
                return WorkbenchSingleton.SafeThreadFunction(CloseWorkbenchInternal, force);
            }
            else
            {
                return CloseWorkbenchInternal(force);
            }
        }
        bool CloseWorkbenchInternal(bool force)
        {
            //foreach (IWorkbenchWindow window in WorkbenchSingleton.Workbench.WorkbenchWindowCollection.ToArray())
            //{
            //    if (!window.CloseWindow(force))
            //        return false;
            //}
            WorkbenchSingleton.Workbench.Close();
            return true;
        }
    }
}
